/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。
 * 
 * 指定登记&发行网站： https://www.zhiqim.com/ 欢迎加盟知启蒙，[编程有你，知启蒙一路随行]。
 *
 * 本文采用《知启蒙许可证》，除非符合许可证，否则不可使该文件！
 * 1、您可以免费使用、修改、合并、出版发行和分发，再授权软件、软件副本及衍生软件；
 * 2、您用于商业用途时，必须在原作者指定的登记网站进行实名登记；
 * 3、您在使用、修改、合并、出版发行和分发时，必须包含版权声明、许可声明，及保留原作者的著作权、商标和专利等知识产权；
 * 4、您在互联网、移动互联网等大众网络下发行和分发再授权软件、软件副本及衍生软件时，必须在原作者指定的发行网站进行发行和分发；
 * 5、您可以在以下链接获取一个完整的许可证副本。
 * 
 * 许可证链接：http://zhiqim.org/licenses/LICENSE.htm
 *
 * 除非法律需要或书面同意，软件由原始码方式提供，无任何明示或暗示的保证和条件。详见完整许可证的权限和限制。
 */
package com.zhiqim.fadfox.manager.action;

import java.util.List;
import java.util.Random;

import com.zhiqim.fadfox.bootstrap.Global;
import com.zhiqim.fadfox.httpd.HttpRequest;
import com.zhiqim.fadfox.httpd.context.extend.StdSwitchAction;
import com.zhiqim.fadfox.manager.FmrBootstrap;
import com.zhiqim.fadfox.manager.FmrConstants;
import com.zhiqim.fadfox.manager.FmrPassworder;
import com.zhiqim.fadfox.manager.FmrSessionUser;
import com.zhiqim.fadfox.manager.dao.FmrDeptDao;
import com.zhiqim.fadfox.manager.dbo.FmrAvatar;
import com.zhiqim.fadfox.manager.dbo.FmrDept;
import com.zhiqim.fadfox.manager.dbo.FmrOperator;
import com.zhiqim.fadfox.manager.dbo.FmrOperatorLog;
import com.zhiqim.fadfox.manager.dbo.FmrOperatorRule;
import com.zhiqim.fadfox.orm.FTable;
import com.zhiqim.fadfox.orm.fdbo.Selector;
import com.zhiqim.fadfox.orm.fdbo.Updater;
import com.zhiqim.fadfox.paging.PageResult;
import com.zhiqim.fadfox.transaction.Transaction;
import com.zhiqim.fadfox.transaction.TransactionManager;
import com.zhiqim.fadfox.tree.Tree;
import com.zhiqim.fadfox.tree.TreeBuilder;
import com.zhiqim.fadfox.util.Arrays;
import com.zhiqim.fadfox.util.DateTimes;
import com.zhiqim.fadfox.util.Randoms;
import com.zhiqim.fadfox.util.Validates;
import com.zhiqim.fadfox.validate.ones.IsNotEmpty;
import com.zhiqim.fadfox.validate.onex.IsEmail;
import com.zhiqim.fadfox.validate.onex.IsIP;
import com.zhiqim.fadfox.validate.onex.IsMobile11;
import com.zhiqim.fadfox.validate.onex.IsUserCode;
import com.zhiqim.fadfox.validate.onex.IsUserPass;

/**
 * 操作员/管理员管理
 *
 * @version v1.0.0 @author zouzhigang 2015-5-28 新建与整理
 */
public class OperatorAction extends StdSwitchAction implements FmrConstants
{
    protected void validateId(HttpRequest request)
    {
        request.addValidate(new IsUserCode("operatorCode","操作员编码由2-16位字母数字汉字开头，字母汉字数字特殊符号组成"));
    }
    
    protected void validateForm(HttpRequest request)
    {
        request.addValidate(new IsUserCode("operatorCode","操作员编码由2-16位字母数字汉字开头，字母汉字数字特殊符号组成"));
        request.addValidate(new IsNotEmpty("operatorName", "操作员名称不能为空"));
        request.addValidate(new IsNotEmpty("operatorStatus", "操作员状态不能为空"));
        request.addValidate(new IsIP("operatorIp", "请输入正确的IP地址", true));
        request.addValidate(new IsMobile11("operatorMobile", "请输入正确的手机号", true));
        request.addValidate(new IsEmail("operatorEmail", "请输入正确的手机号", true));
    }

    protected void list(HttpRequest request) throws Exception
    {
        int page = request.getParameterInt("page");
        int pageSize = request.getContextAttributeInt(FMR_PAGE_SIZE, 20);
        long deptId = request.getParameterLong("deptId");
        String operatorCode = request.getParameter("operatorCode");
        String operatorName = request.getParameter("operatorName");
        
        List<FmrDept> list = FmrDeptDao.list();
        Tree<FmrDept> tree = TreeBuilder.newTree(list, "parentId", "deptId");
        request.setAttribute("tree", tree);
        
        FmrSessionUser sessionUser = request.getSessionUser(FmrSessionUser.class);
        Selector selector = new Selector();
        if (sessionUser.isAdmin())
        {//管理员可以看到管理员和操作员
            selector.addMustThenG("operatorType", 0);
        }
        else
        {//操作员只能查操作员
            selector.addMustThenG("operatorType", 1);
        }
        
        selector.addMaybeLike("operatorDept", deptId);
        selector.addMaybeLike("operatorCode", operatorCode);
        selector.addMaybeLike("operatorName", operatorName);
        selector.addOrderbyAsc("operatorType");
        selector.addOrderbyAsc("operatorStatus");
        selector.addOrderbyAsc("operatorCreated");
        
        PageResult<FmrOperator> result = Global.get(FTable.class).page(FmrOperator.class, page, pageSize, selector);
        result.addConditionMap(request.getParameterMap());
        
        for (FmrOperator operator : result.list())
        {
            toDeptName(list, operator);
        }
        
        request.setAttribute("result", result);
    }
    
    
    private void toDeptName(List<FmrDept> deptList, FmrOperator operator)
    {
        operator.setOperatorCreated("");
        
        long[] deptIds = Arrays.toLongArray(operator.getOperatorDept());
        for (long deptId : deptIds)
        {
            for (FmrDept dept : deptList)
            {
                if (dept.getDeptId() == deptId)
                {
                    if (Validates.isEmpty(operator.getOperatorCreated()))
                        operator.setOperatorCreated(dept.getDeptName());
                    else
                        operator.setOperatorCreated(operator.getOperatorCreated() + "," + dept.getDeptName());
                    break;
                }
            }
        }
    }
    
    protected void add(HttpRequest request) throws Exception
    {
        request.addValidate(new IsUserPass("operatorPass", "操作员密码不合法，要求6-16位（大小写字母数字和特殊字符必须四选三）"));
    }

    protected void insert(HttpRequest request) throws Exception
    {
        String dateTime = DateTimes.getDateTimeString();
        String operatorCode = request.getParameter("operatorCode");
        String operatorPass = request.getParameter("operatorPass");
        int operatorStatus = request.getParameterInt("operatorStatus");
        int operatorType = request.getParameterInt("operatorType", 2);//默认为操作员
        String operatorName = request.getParameter("operatorName");
        String operatorIp = request.getParameter("operatorIp");
        String operatorMobile = request.getParameter("operatorMobile");
        String operatorEmail = request.getParameter("operatorEmail");
        
        if(Global.get(FTable.class).count(FmrOperator.class, operatorCode) > 0)
        {
            request.returnHistory("该操作员编码已经存在，请重新输入");
            return;
        }
        
        if(!Validates.isUserPass(operatorPass))
        {
            request.returnHistory("请输入6-16位操作员密码（大小写字母数字和特殊字符必须四选三）");
            return;
        }
        
        long operatorAvatar = 0;
        PageResult<FmrAvatar> result = Global.get(FTable.class).page(FmrAvatar.class, 1, 10, new Selector("avatarId", "avatarType", 0));
        if(result.size() > 0)
        {//随机取一个系统头像
            int ind = new Random().nextInt(result.size());
            operatorAvatar = result.list().get(ind).getAvatarId();
        }
        
        FmrPassworder passworder = FmrBootstrap.getFmrPassworder();
        String operatorPassSalt = Randoms.lettersDigitsSecure(64);
        operatorPass = passworder.encode(operatorCode, operatorPass, operatorPassSalt);
        
        FmrOperator operator = new FmrOperator();
        operator.setOperatorCode(operatorCode);
        operator.setOperatorPass(operatorPass);
        operator.setOperatorPassSalt(operatorPassSalt);
        operator.setOperatorStatus(operatorStatus);
        operator.setOperatorType(operatorType);
        operator.setOperatorName(operatorName);
        operator.setOperatorIp(operatorIp);
        operator.setOperatorAvatar(operatorAvatar);
        operator.setOperatorMobile(operatorMobile);
        operator.setOperatorEmail(operatorEmail);
        operator.setOperatorCreated(dateTime);
        operator.setOperatorModified(dateTime);
        Global.get(FTable.class).insert(operator);
    }

    protected void modify(HttpRequest request) throws Exception
    {
        request.addValidate(new IsUserPass("operatorPass", "操作员密码不合法，要求6-16位（大小写字母数字和特殊字符必须四选三）", true));
        String operatorCode = request.getParameter("operatorCode"); 
        
        FmrOperator operator = Global.get(FTable.class).item(FmrOperator.class, operatorCode);
        if(operator == null)
        {
            request.returnHistory("该操作员不存在，请重新选择");
            return;
        }
        request.setAttribute("operator", operator);
    }
    
    protected void update(HttpRequest request) throws Exception
    {
        String dateTime = DateTimes.getDateTimeString();
        String operatorCode = request.getParameter("operatorCode");
        String operatorName = request.getParameter("operatorName");
        String operatorPass = request.getParameter("operatorPass");
        int operatorStatus = request.getParameterInt("operatorStatus");
        String operatorIp = request.getParameter("operatorIp");
        String operatorMobile = request.getParameter("operatorMobile");
        String operatorEmail = request.getParameter("operatorEmail");
        
        Updater updater = new Updater();
        updater.addMaybe("operatorCode", operatorCode);
        updater.addField("operatorName", operatorName);
        if(Validates.isNotEmpty(operatorPass))
        {
            if(!Validates.isUserPass(operatorPass))
            {
                request.returnHistory("请输入6-16位操作员密码（大小写字母数字和特殊字符必须四选三）");
                return;
            }
            
            FmrPassworder passworder = FmrBootstrap.getFmrPassworder();
            String operatorPassSalt = Randoms.lettersDigitsSecure(64);
            
            operatorPass = passworder.encode(operatorCode, operatorPass, operatorPassSalt);
            updater.addField("operatorPass", operatorPass);
            updater.addField("operatorPassSalt", operatorPassSalt);
        }
        
        updater.addField("operatorStatus", operatorStatus);
        updater.addField("operatorIp", operatorIp);
        updater.addField("operatorMobile", operatorMobile);
        updater.addField("operatorEmail", operatorEmail);
        updater.addField("operatorModified", dateTime);
        Global.get(FTable.class).update(FmrOperator.class, updater);
    }

    protected void delete(HttpRequest request) throws Exception
    {
        String operatorCode = request.getParameter("operatorCode");
        FmrOperator operator = Global.get(FTable.class).item(FmrOperator.class, operatorCode);
        if (operator == null)
        {
            request.returnHistory("该操作员不存在");
            return;
        }
        
        Selector selector = new Selector("operatorCode", operatorCode);
        if (Global.get(FTable.class).count(FmrOperatorLog.class, selector) > 0)
        {
            request.returnHistory("该操作员已有操作日志，不允许删除，只能停用");
            return;
        }
        
        Transaction tx = null;
        try
        {
            tx = TransactionManager.beginTransaction();
        
            FmrAvatar avatar = Global.get(FTable.class).item(FmrAvatar.class, operator.getOperatorAvatar());
            if (avatar != null && avatar.getAvatarType() == 1)
            {//删除操作员头像
                Global.get(FTable.class).delete(FmrAvatar.class, operator.getOperatorAvatar());
            }
            
            //删除操作员&权限
            Global.get(FTable.class).delete(FmrOperator.class, operatorCode);
            Global.get(FTable.class).delete(FmrOperatorRule.class, selector);
            
            tx.commit();
        }
        catch(Exception e)
        {
            if (tx != null) tx.rollback();
        }
        finally
        {
            if (tx != null) tx.close();
        }
    }
}
